#include "socket_local_read.h"

#include "socket_private_acl.h"
#include "business_def.h"
#include "verifyforcontrolcache.h"
#include "pfunc.h"
#include "Log.h"
#ifdef __linux__
#include <stdexcept>
#endif
#ifdef WIN32
#define usleep(x) Sleep(x)
#endif

SocketLocalRead::SocketLocalRead(void)
	: running(true) 
	, socket_acl(NULL)
	, ptr_bdef(BusinessDef::getInstance())
	, is_Verification(false)
	, ptr_vcc(VerifyForControlCache::getInstance())
	, read_datas(new QueueData<DataFromChannel>("local_socket_read"))
	, socket_write_queue(QueueDataSingle<DataToGather>::getInstance())
{
	is_Verification = ptr_bdef->getVerificationFunc();
}

SocketLocalRead::~SocketLocalRead(void)
{
	running = false;
}

void SocketLocalRead::setPrivateDataPtr(SocketPrivate_ACL *socket_acl_)
{
	if (NULL != socket_acl_)
	{
		socket_acl = socket_acl_;
	}
}

void* SocketLocalRead::run()
{
	if (NULL == socket_acl) 
	{
		CLogger::createInstance()->Log(MsgError,
			"MySocketLocalRD start fail for socket_acl is NULL"
			",[%s %s %d]!"
			, __FILE__, __FUNCTION__, __LINE__);
		return 0;
	}
	std::map<KeyObj_Client, RDClient> bufs;
	DataFromChannel data_from_client;
	while (running)
	{
		int re = socket_acl->Read(bufs);
		if (re < 0) 
		{
#ifdef _DEBUG
			Print_NOTICE("Read Data Failed \n!");
#else
			;
#endif
		}
		else 
		{
			try {
				std::map<KeyObj_Client, RDClient>::iterator it = bufs.begin();
				while (it != bufs.end())
				{
					unsigned char * buff = it->second.Buf;
					int start_pos = 0;
					unsigned char ctype = 0;
					printf("read:");
					for (int i = 0; i < it->second.len; i++)
					{
						printf("%02X ",buff[i]);
						if (buff[i] > 0xf0) 
						{
							if (buff[i] == 0xff) 
							{
								if (ctype) 
								{
									ctype = 0;
									DataFromChannel rdata(buff + start_pos, i - start_pos + 1, it->first.m_ipStr);
									read_datas->add(rdata);
									start_pos = i + 1;
								}
							}
							else 
							{
								ctype = buff[i];
								start_pos = i;
							}
						}
					}
					printf("\n");
					buff = NULL;
					if (start_pos < it->second.len)
					{
						RDClient _newrd(it->second.Buf + start_pos, it->second.len - start_pos);
						it->second = _newrd;
						it++;
					}
					else 
					{
#ifdef WIN32
						it = bufs.erase(it);
#else
						std::map<KeyObj_Client, RDClient>::iterator ittemp = it++;
						bufs.erase(ittemp);
#endif
					}
				}
			}
			catch (const std::exception& e)
			{
				CLogger::createInstance()->Log(MsgError,
					"MySocketLocalRD::Running false[%s],[%s %s %d]!"
					, e.what()
					, __FILE__, __FUNCTION__, __LINE__);
			}
			catch (...) 
			{
				CLogger::createInstance()->Log(MsgError,
					"SocketLocalRead::run,[%s %s %d]!"
					, __FILE__, __FUNCTION__, __LINE__);
			}
		}

		while (read_datas->getFirst(data_from_client))
		{
			this->AddFrame(data_from_client.flag, data_from_client.Buf, data_from_client.len);
			read_datas->removeFirst();
		}
		usleep(1);
	}
	return NULL;
};

int SocketLocalRead::AddFrame(const std::string link, const unsigned char *buf, int len)
{
	//const unsigned char * buff = buf;
	try {
		unsigned char * pBuf = new unsigned char[len];
		// int nLen = pyfree::uncode(buf, len, pBuf);
		pyfree::uncode(buf, len, pBuf);
		unsigned char type = pBuf[0];
		int idx = 1;
		switch (type)
		{
		case 0XF6:
		{
			int blen = pBuf[idx++];
			blen += (pBuf[idx++] << 8);
			//
			int devID = 0;
			devID += pBuf[idx++];
			devID += (pBuf[idx++] << 8);
			devID += (pBuf[idx++] << 16);
			devID += (pBuf[idx++] << 24);
			//
			int pID = 0;
			pID += pBuf[idx++];
			pID += (pBuf[idx++] << 8);
			pID += (pBuf[idx++] << 16);
			pID += (pBuf[idx++] << 24);
			//
			float Value = float(0.0);
			unsigned char* fval = (unsigned char*)&Value;
			fval[3] = pBuf[idx++];
			fval[2] = pBuf[idx++];
			fval[1] = pBuf[idx++];
			fval[0] = pBuf[idx++];
			fval = NULL;
			//end
			unsigned char endflag = pBuf[idx++];
			//
// #ifdef _DEBUG
			Print_NOTICE("read data 0XF6:link[%s],DevID[%d],pID[%d],val[%.3f]],endflag[%02X]\n"
				, link.c_str(), devID, pID, Value, endflag);
// #endif // _DEBUG

			this->setPValue(devID, pID, Value);
		}
		break;
		default:
		{
			delete[] pBuf;
			pBuf = NULL;
			//
			char warBuf[128] = { 0 };
			sprintf(warBuf, "SocketLocalRead::AddFrame For Unkown Type(%02X)", type);
			#ifdef WIN32
			throw std::exception(warBuf);
			#else
			throw std::domain_error(warBuf);
			#endif
			//throw type;
		}
		//break;
		}
		delete[] pBuf;
		pBuf = NULL;
		return 1;
	}
	//catch (unsigned char type)
	//{
	//	CLogger::createInstance()->Log(MsgInfo,
	//		"Data uncode(%s,%s,%d) and type[%02X] is no support,[%s %s %d]"
	//		, link.c_str(), buf, len
	//		, type
	//		, __FILE__, __FUNCTION__, __LINE__);
	//}
	catch (const std::exception& e)
	{
		CLogger::createInstance()->Log(MsgError,
			"Data uncode(%s,%s,%d) have error[%s],[%s %s %d]!"
			, link.c_str(), buf, len
			, e.what()
			, __FILE__, __FUNCTION__, __LINE__);
	}
	catch (...)
	{
		CLogger::createInstance()->Log(MsgError,
			"Data uncode error[%s,%s,%d],[%s %s %d]!"
			, link.c_str(), buf, len
			, __FILE__, __FUNCTION__, __LINE__);
	}
	return -1;
};

void SocketLocalRead::setPValue(int devID, int pID, float val)
{
	unsigned long taskID = pyfree::getTaskIDFromDateTime();
	PFrom _pfrom;
	if (ptr_bdef->getFromInfo(devID, static_cast<int>(pID), _pfrom))
	{
		float _val = val;
		ptr_bdef->getCValue(devID, static_cast<unsigned int>(pID), _val);
		DataToGather wd(_pfrom.ipLong, OnSet, _pfrom.pID, _pfrom.pType, _val, 0, "LocalClient_Control", taskID);
		socket_write_queue->add(wd);

		CLogger::createInstance()->Log(MsgInfo
			, "TaskID[%lu] and down_node[1] setPValue from LocalClient,time(%s),devID(%ld),pID(%ld),val(%.3f)"
			",down_control_map, ip[%s],pID(%d),pType(%d),val(%.3f)"
			, taskID
			, pyfree::getCurrentTime().c_str()
			, devID, pID, val
			, _pfrom.ipStr.c_str()
			, _pfrom.pID, static_cast<int>(_pfrom.pType), _val);
		//
		if (is_Verification) {
			VerificationCache vit;
			vit.execTime = pyfree::getCurrentTimeByFormat("%04d%02d%02dT%02d%02d%02dZ");
			vit.taskID = taskID;
			vit.taskDesc = "LocalClient_Control";
			vit.devID = devID;
			vit.devDesc = _pfrom.devDesc;
			vit.pID = pID;
			vit.pDesc = _pfrom.pDesc;
			vit.pType = static_cast<unsigned int>(_pfrom.pType);
			vit.val = val;
			vit.limitTimeForCheck = static_cast<unsigned int>(time(NULL)) + 5;
			vit.eway_ = _pfrom.eway;
			ptr_vcc->addVerifyData(vit);
		}
	}
	else 
	{
		PValueRet pret(val);
		ptr_bdef->setHValue(devID, static_cast<unsigned int>(pID), pret);
		CLogger::createInstance()->Log(MsgInfo
			, "TaskID[%lu] and down_node[1] setPValue from LocalClient and down_node[0],time(%s),devID(%ld),pID(%ld),val(%.3f)"
			",ditect set val to virtual ponit control"
			, taskID, pyfree::getCurrentTime().c_str()
			, devID, pID, pret.val_actual);
	}
};
